package virtualinit.util;

import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 简单日志类
 * time[thread-id:thread-name]
 */
public class Log {
    private Log(){}

    public static final Log instance = new Log();

    public  boolean simplePrint = false;
     LogLevel logLevel = LogLevel.DEBUG;

    public  void info(String msg, Object... args) {
        if (logLevel.isInfoEnable()) {
            println(LogLevel.INFO, msg, null, args);
        }
    }

    public  void info(String msg, Throwable e, Object... args) {
        if (logLevel.isInfoEnable()) {
            println(LogLevel.INFO, msg, e, args);
        }
    }

    public  void debug(String msg, Object... args) {
        if (logLevel.isDebugEnable()) {
            println(LogLevel.INFO, msg, null, args);
        }
    }

    public  void debug(String msg, Throwable e, Object... args) {
        if (logLevel.isDebugEnable()) {
            println(LogLevel.INFO, msg, e, args);
        }
    }

    public  void error(String msg, Throwable e, Object... args) {
        if (logLevel.isErrorEnable()) {
            printlnErr(LogLevel.INFO, msg, e, args);
        }
    }

    public  void error(String msg, Object... args) {
        if (logLevel.isErrorEnable()) {
            printlnErr(LogLevel.ERROR, msg, null, args);
        }
    }

    public  void println(LogLevel level, String msg, Throwable e, Object... args) {
        print(System.out, level, CommonUtil.formatBraces(msg, args) + CommonUtil.exceptionToString(e));
    }


    public  void printlnErr(LogLevel level, String msg, Throwable e, Object... args) {
        print(System.err, level, CommonUtil.formatBraces(msg, args) + CommonUtil.exceptionToString(e));
    }

    private  void print(PrintStream out, LogLevel level, String msg) {
        if (msg != null || msg.length() != 0) {
            if (simplePrint)
                out.println(msg);
            else
                prettyPrint(out, level, msg);
        }
    }

    private  void prettyPrint(PrintStream out, LogLevel level, String msg) {
        String f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
        StringBuilder sb = new StringBuilder(100);
        Thread t = Thread.currentThread();
        sb.append(f).append(" [").append(t.getId()).append(':').append(t.getName()).append("] ");
        sb.append(level.name()).append(" : ").append(msg);
        out.println(sb.toString());
    }


    public enum LogLevel {
        DEBUG(1), INFO(2), ERROR(3),
        ;

        private final int levelId;

        LogLevel(int levelId) {
            this.levelId = levelId;
        }

        public boolean isInfoEnable() {
            return INFO.levelId >= levelId;
        }

        public boolean isDebugEnable() {
            return DEBUG.levelId >= levelId;
        }

        public boolean isErrorEnable() {
            return ERROR.levelId >= levelId;
        }
    }

}
